home *** CD-ROM | disk | FTP | other *** search
/ Macwelt 1 / Macwelt DVD 1.toast / Web-Publishing / HTML-Editoren / Alpha ƒ / Tcl / Modes / HTML and CSS Modes / htmlElems.tcl < prev    next >
Encoding:
Text File  |  2001-02-01  |  36.3 KB  |  1,126 lines

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #  HTML mode - tools for editing HTML documents
  4.  # 
  5.  #  FILE: "htmlElems.tcl"
  6.  #                                    created: 01-01-25 17.55.29 
  7.  #                                last update: 01-02-01 19.17.11 
  8.  #  Author: Johan Linde
  9.  #  E-mail: <alpha_www_tools@go.to>
  10.  #     www: <http://go.to/alpha_www_tools>
  11.  #  
  12.  # Version: 3.0
  13.  # 
  14.  # Copyright 1996-2001 by Johan Linde
  15.  #  
  16.  # This program is free software; you can redistribute it and/or modify
  17.  # it under the terms of the GNU General Public License as published by
  18.  # the Free Software Foundation; either version 2 of the License, or
  19.  # (at your option) any later version.
  20.  # 
  21.  # This program is distributed in the hope that it will be useful,
  22.  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  23.  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24.  # GNU General Public License for more details.
  25.  # 
  26.  # You should have received a copy of the GNU General Public License
  27.  # along with this program; if not, write to the Free Software
  28.  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29.  # 
  30.  # ###################################################################
  31.  ##
  32.  
  33. #===============================================================================
  34. # This file contains procs for various menu items found in the element submenus.
  35. #===============================================================================
  36.  
  37. #===============================================================================
  38. # ◊◊◊◊ Insert/Remove linebreaks ◊◊◊◊ #
  39. #===============================================================================
  40.  
  41. # Insert a <BR> in the end of every line in selection.
  42.  
  43. proc html::InsertLineBreaks {} {
  44.     if {![isSelection]} {
  45.         beep
  46.         message "No selection."
  47.         return
  48.     }
  49.     set cr [html::CRcharacter]
  50.     regsub -all $cr [getSelect] "[html::SetCase <BR>]$cr" text
  51.     replaceText [getPos] [selEnd] $text
  52. }
  53.  
  54. # Remove all <BR> in selection.
  55. proc html::RemoveLineBreaks {} {
  56.     if {![isSelection]} {
  57.         beep
  58.         message "No selection."
  59.         return
  60.     }
  61.     regsub -all -nocase "<BR(\[ \t\r\n\]+\[^<>\]*>|>)" [getSelect] "" text
  62.     if {$text != [getSelect]} {
  63.         replaceText [getPos] [selEnd] $text
  64.     }
  65. }
  66.  
  67. #===============================================================================
  68. # ◊◊◊◊ Insert Paragraphs ◊◊◊◊ #
  69. #===============================================================================
  70.  
  71. # Insert <P> at empty lines in selection, and in the beginning of the selection.
  72. # Several empty lines are contracted to one.
  73. proc html::InsertParagraphs {} {
  74.     global HTMLmodeVars
  75.     if {![isSelection]} {
  76.         beep
  77.         message "No selection."
  78.         return
  79.     }
  80.     set cr [html::CRcharacter]
  81.     set pIsContainer [lcontains HTMLmodeVars(optionalClosing) P]
  82.     html::indentCR P
  83.     if {[set oelem [html::OpenElem P "" 0]] == ""} {return}
  84.     set pind ""
  85.     if {[lcontains HTMLmodeVars(indentElements) P]} {set pind "\t"}
  86.     set text "$cr$oelem"
  87.     if {$crAftP} {append text $cr}
  88.     set prevLineEmpty 1
  89.     
  90.     foreach ln [split [string trimright [string trimleft [getSelect] $cr]] $cr] {
  91.         regexp {[ \t]*} $ln lntest
  92.         # Only add <P> if previous line was not empty.
  93.         if {$ln == $lntest && !$prevLineEmpty} {
  94.             set prevLineEmpty 1
  95.             if {$pIsContainer} {
  96.                 append text [html::CloseElem P]
  97.                 if {${blAft/P} || ${crAft/P}} {append text $cr}
  98.                 if {${blAft/P}} {append text $cr}
  99.                 append text $oelem
  100.                 if {$crAftP} {append text $cr}
  101.             } else {
  102.                 append text $oelem
  103.                 if {$crAftP} {append text $cr}
  104.             }
  105.         } else {
  106.             # Skip an empty line which follows another empty line.
  107.             if {$ln != $lntest} {
  108.                 set prevLineEmpty 0
  109.                 append text "$pind[string trim $ln]$cr"
  110.             }
  111.         }
  112.     }
  113.     if {$pIsContainer} {
  114.         append text [html::CloseElem P]
  115.         if {${blAft/P}} {
  116.             append text    [html::CloseCR2 [selEnd]]
  117.         } elseif {${crAft/P}} {append text    [html::CloseCR [selEnd]]}
  118.     }
  119.     deleteText [getPos] [selEnd]
  120.     HTML::indentLine
  121.     if {[pos::compare [set p [text::firstNonWsLinePos [getPos]]] > [getPos]]} {goto $p}
  122.     elec::Insertion $text
  123. }
  124.  
  125. #===============================================================================
  126. # ◊◊◊◊ Make list ◊◊◊◊ #
  127. #===============================================================================
  128.  
  129. # Make list items from selection.
  130. proc html::MakeList {} {
  131.     global HTMLmodeVars html::HideDeprecated
  132.     
  133.     set isContainer [lcontains HTMLmodeVars(optionalClosing) LI]
  134.     
  135.     if {![isSelection]} {
  136.         beep
  137.         message "No selection."
  138.         return
  139.     }
  140.     if {${html::HideDeprecated} || $HTMLmodeVars(hideDeprecated)} {
  141.         set men {UL UL OL None}
  142.     } else {
  143.         set men {UL UL OL DIR MENU None}
  144.     }
  145.  
  146.     set values [dialog -w 220 -h 130 -t "Make list" 50 10 210 30 \
  147.     -t "Each item begins with:" 10 40 160 55 -e "*" 170 40 200 55 \
  148.     -t "List:" 10 65 50 85 -m $men 55 65 200 85 \
  149.     -b OK 20 100 85 120 -b Cancel 105 100 170 120]
  150.     
  151.     if {[lindex $values 3]} {return}
  152.     set itemStr [string trim [lindex $values 0]]
  153.     set listtype [lindex $values 1]
  154.     set indentContent [lcontains HTMLmodeVars(indentElements) $listtype]
  155.     set indentLI [lcontains HTMLmodeVars(indentElements) LI]
  156.     if {$listtype != "None"} {html::indentCR $listtype}
  157.     html::indentCR LI
  158.     
  159.     if {![string length $itemStr]} {
  160.         beep
  161.         message "You must give a string which each item begins with."
  162.         return
  163.     }
  164.     set startPos [getPos]
  165.     set endPos [selEnd]
  166.     if {[catch {search -s -f 1 -i 0 -r 0 -m 0 -- $itemStr $startPos} res] || \
  167.     [lindex $res 1] > $endPos} {
  168.         beep 
  169.         message "No list item in selection."
  170.         return
  171.     }
  172.     # Check that the selections begins with a list item.
  173.     set preText [getText $startPos [lindex $res 0]]
  174.     if {![is::Whitespace $preText]} {
  175.         beep
  176.         message "There is some text before the first list item."
  177.         return
  178.     }
  179.     set indent ""
  180.     set curr ""
  181.     set text ""
  182.     set cr [expr {2 - [string length [html::OpenCR 1]]}]
  183.     if {$listtype != "None"} {
  184.         html::crBefore [set blBef$listtype] [set crBef$listtype] text $indent cr curr [html::SetCase <$listtype>]
  185.         html::crAfter [set blAft$listtype] [set crAft$listtype] text indent cr curr 0 $indentContent
  186.     }
  187.     
  188.     # Get each list item.
  189.     set startPos [lindex $res 1]
  190.     while {![catch {search -s -f 1 -i 0 -r 0 -m 0 -- $itemStr $startPos} res2] && \
  191.       [pos::compare [lindex $res2 1] <= $endPos]} {
  192.         html::crBefore $blBefLI $crBefLI text $indent cr curr [html::SetCase <LI>]
  193.         html::crAfter $blAftLI $crAftLI text indent cr curr 0 $indentLI
  194.         append curr [html::prepareForBreaking [string trim [getText $startPos [lindex $res2 0]]]]
  195.         if {$isContainer} {
  196.             html::crBefore ${blBef/LI} ${crBef/LI} text $indent cr curr [html::CloseElem LI]
  197.             html::crAfter ${blAft/LI} ${crAft/LI} text indent cr curr 1 $indentLI
  198.         }
  199.         set startPos [lindex $res2 1]
  200.     }
  201.     html::crBefore $blBefLI $crBefLI text $indent cr curr [html::SetCase <LI>]
  202.     html::crAfter $blAftLI $crAftLI text indent cr curr 0 $indentLI
  203.     append curr [html::prepareForBreaking [string trim [getText $startPos $endPos]]]
  204.     if {$isContainer} {
  205.         html::crBefore ${blBef/LI} ${crBef/LI} text $indent cr curr [html::CloseElem LI]
  206.     }
  207.     if {$listtype != "None"} {
  208.         if {$isContainer} {html::crAfter ${blAft/LI} ${crAft/LI} text indent cr curr 1 $indentLI}
  209.         html::crBefore [set blBef/$listtype] [set crBef/$listtype] text $indent cr curr [html::CloseElem $listtype]
  210.         append text [html::BreakIntoLines $curr $indent]
  211.         if {[set crAft/$listtype]} {append text [html::CloseCR [selEnd]]}
  212.         if {[set blAft/$listtype]} {append text [html::CloseCR2 [selEnd]]}
  213.     } else {
  214.         append text [html::BreakIntoLines $curr $indent]
  215.         if {$isContainer} {
  216.             if {[set crAft/LI]} {append text [html::CloseCR [selEnd]]}
  217.             if {[set blAft/LI]} {append text [html::CloseCR2 [selEnd]]}
  218.         } else {
  219.             append text [html::CloseCR [selEnd]]
  220.         }
  221.     }
  222.     deleteText [getPos] [selEnd]
  223.     HTML::indentLine
  224.     if {[pos::compare [set p [text::firstNonWsLinePos [getPos]]] > [getPos]]} {goto $p}
  225.     elec::Insertion $text
  226. }
  227.  
  228. #===============================================================================
  229. # ◊◊◊◊ Building lists ◊◊◊◊ #
  230. #===============================================================================
  231.  
  232. # Ask for input how to build a list. Returns "number of items" and
  233. # "ask for list item attributes". Returns "" if canceled or any problem.
  234. proc html::ListQuestions {ltype liattr lipr} {
  235.     global HTMLmodeVars
  236.     
  237.     set promptNoisily $HTMLmodeVars(promptNoisily)
  238.     if {[string length $liattr]} {
  239.         set usedatts [html::GetUsed $liattr]
  240.     } else {
  241.         set usedatts [html::GetUsed LI]
  242.     }
  243.     if {$lipr != "LI"} { 
  244.         eval lappend usedatts [html::GetUsed DD]
  245.     }
  246.     if {$HTMLmodeVars(useBigWindows)} {
  247.         set it {0 0 3 0}
  248.         while {1} {
  249.             set txt "dialog -w 280 -h 130 -b OK 20 100 85 120 -b Cancel 110 100 175 120 \
  250.             -t {$ltype list} 100 10 250 30 \
  251.             -t {How many items?} 10 40 150 60 -e [list [lindex $it 2]] 160 40 180 55"
  252.             if {[llength $usedatts]} {
  253.                 append txt " -c {Ask for attributes for each $lipr} [lindex $it 3] \
  254.                 10 70 330 85"
  255.             }
  256.             set it [eval $txt]
  257.             if {[lindex $it 1]} {return}
  258.             set items [lindex $it 2]
  259.             if {[llength $it] == 4 && [lindex $it 3]} {
  260.                 set askForLiAttr 1
  261.             } else {
  262.                 set askForLiAttr 0
  263.             }
  264.             
  265.             if {![is::UnsignedInteger $items] && $ltype != "DL"} {
  266.                 alertnote "Invalid input: non-negative integer required"
  267.             } elseif {![is::PositiveInteger $items] && $ltype == "DL"} {
  268.                 alertnote "Invalid input: positive integer required"
  269.             } else {
  270.                 break
  271.             }
  272.         }
  273.     } else {
  274.         if {$promptNoisily} {beep}    
  275.         global html::StatusNumRegexp
  276.         set html::StatusNumRegexp {^[0-9]*$}
  277.         while {[catch {html::statusPrompt "" "$ltype list: How many items? " html::NumberStatusFunc} items]} {
  278.             if {$items == "Cancel all!"} {message "Cancel"; return}
  279.         }
  280.         if {![is::UnsignedInteger $items] && $ltype != "DL"} {
  281.             beep; message "Invalid input: non-negative integer required."; return
  282.         } elseif {![is::PositiveInteger $items] && $ltype == "DL"} {
  283.             beep; message "Invalid input: positive integer required."; return
  284.         }
  285.         if {[llength $usedatts] && $items} {
  286.             if {$promptNoisily} {beep}    
  287.             while {[catch {html::statusPrompt "" "Ask for attributes for each $lipr? \[n\] " \
  288.             html::StatusAskYesOrNo} v]} {
  289.                 if {$v == "Cancel all!"} {message "Cancel"; return}
  290.             }
  291.             if {$v == "yes"} {
  292.                 set askForLiAttr 1
  293.             } else {
  294.                 set askForLiAttr 0
  295.             }
  296.         } else {
  297.             set askForLiAttr 0
  298.         }
  299.     }
  300.     return [list $items $askForLiAttr]
  301. }
  302.     
  303.  
  304. # Lists: Puts <cr>s before and after a list, inserts <li>, leaves the
  305. # insertion point there.  If anything is selected, makes it the first item.
  306. proc html::BuildList {ltype {liattr ""} {listattr ""}} {
  307.     global HTMLmodeVars htmlCurSel htmlIsSel
  308.  
  309.     if {[html::IsInContainer STYLE]} {
  310.         replaceText [getPos] [selEnd] $ltype
  311.         return
  312.     }
  313.     
  314.     set useTabMarks $HTMLmodeVars(useTabMarks)
  315.     set containers [lcontains HTMLmodeVars(optionalClosing) LI]
  316.     
  317.     set listStr [html::ListQuestions $ltype $liattr LI]
  318.     if {![llength $listStr]} {
  319.         return
  320.     } else {
  321.         set items [lindex $listStr 0]
  322.         set askForLiAttr [lindex $listStr 1]
  323.     }
  324.  
  325.     # If zero list items, just make an html::Tag
  326.     if {$items == 0} {
  327.         html::Tag $ltype $listattr
  328.         return
  329.     }
  330.     
  331.     html::indentCR $ltype LI
  332.     html::GetSel
  333.     set sel $htmlCurSel
  334.     set indcont [lcontains HTMLmodeVars(indentElements) $ltype]
  335.     set indLI [lcontains HTMLmodeVars(indentElements) LI]
  336.     set IsSel $htmlIsSel
  337.     set indent ""
  338.     set curr ""
  339.     set text ""
  340.     set cr [expr {2 - [string length [html::OpenCR 1]]}]
  341.     if {[set text1 [html::OpenElem $ltype $listattr 0]] == ""} {return}
  342.     html::crBefore [set blBef$ltype] [set crBef$ltype] text $indent cr curr [html::prepareForBreaking $text1]
  343.     html::crAfter [set blAft$ltype] [set crAft$ltype] text indent cr curr 0 $indcont
  344.     for {set i 0} {$i < $items} {incr i} {
  345.         if {$askForLiAttr} {
  346.             set text1 [html::OpenElem LI $liattr 0]
  347.         } else {
  348.             set text1 [html::SetCase <LI>]
  349.         }
  350.         html::crBefore $blBefLI $crBefLI text $indent cr curr [html::prepareForBreaking $text1]
  351.         html::crAfter $blAftLI $crAftLI text indent cr curr 0 $indLI
  352.         if {$i == 0 && $IsSel} {    
  353.             append curr [html::prepareForBreaking $sel]
  354.         } elseif {$useTabMarks} {
  355.             append curr "•content•"
  356.         }
  357.         if {$containers} {
  358.             html::crBefore ${blBef/LI} ${crBef/LI} text $indent cr curr [html::CloseElem LI]
  359.             html::crAfter ${blAft/LI} ${crAft/LI} text indent cr curr 1 $indLI
  360.         }
  361.     }
  362.     html::crBefore [set blBef/$ltype] [set crBef/$ltype] text $indent cr curr [html::CloseElem $ltype]
  363.     append text [html::BreakIntoLines $curr $indent]
  364.     if {[set crAft/$ltype]} {append text [html::CloseCR]}
  365.     if {[set blAft/$ltype]} {append text [html::CloseCR2 [selEnd]]}
  366.  
  367.     if {$useTabMarks} {append text "•end•"}
  368.     if {$IsSel} { deleteSelection }
  369.     html::elecInsertion text
  370. }
  371.  
  372. proc html::ListItem {} {
  373.     set tag LI
  374.     html::FindList tag
  375.     html::Tag LI $tag
  376. }
  377.  
  378. # Definition Lists (term and description elems)
  379. #
  380. # The selection becomes the *description* (*not* the term)
  381.  
  382. # Build a discursive list
  383. proc html::DefinitionList {} {
  384.     global htmlCurSel htmlIsSel HTMLmodeVars
  385.     
  386.     if {[html::IsInContainer STYLE]} {
  387.         replaceText [getPos] [selEnd] DL
  388.         return
  389.     }
  390.     set containerDT [lcontains HTMLmodeVars(optionalClosing) DT]
  391.     set containerDD [lcontains HTMLmodeVars(optionalClosing) DD]
  392.     set indDL [lcontains HTMLmodeVars(indentElements) DL]
  393.     set indDT [lcontains HTMLmodeVars(indentElements) DT]
  394.     set indDD [lcontains HTMLmodeVars(indentElements) DT]
  395.     html::indentCR DL DT DD
  396.     set useTabMarks    $HTMLmodeVars(useTabMarks)
  397.     
  398.     set listStr [html::ListQuestions DL DT "DT and DD"]
  399.     if {![llength $listStr]} {
  400.         return
  401.     } else {
  402.         set dlEntries [lindex $listStr 0]
  403.         set askForLiAttr [lindex $listStr 1]
  404.     }
  405.     
  406.     html::GetSel
  407.     set Sel $htmlCurSel
  408.     set indent ""
  409.     set curr ""
  410.     set text ""
  411.     set cr [expr {2 - [string length [html::OpenCR 1]]}]
  412.  
  413.     if {[set text1 [html::OpenElem DL "" 0]] == ""} {return}
  414.     html::crBefore $blBefDL $crBefDL text $indent cr curr [html::prepareForBreaking $text1]
  415.     html::crAfter $blAftDL $crAftDL text indent cr curr 0 $indDL
  416.  
  417.     for {set i 0} {$i < $dlEntries} {incr i} {
  418.         if {$askForLiAttr} {
  419.             set text1 [html::OpenElem DT "" 0]
  420.         } else {
  421.             set text1 [html::SetCase <DT>]
  422.         }
  423.         html::crBefore $blBefDT $crBefDT text $indent cr curr [html::prepareForBreaking $text1]
  424.         html::crAfter $blAftDT $crAftDT text indent cr curr 0 $indDT
  425.         if {$useTabMarks} {append curr "•content•"}
  426.         if {$containerDT} {
  427.             html::crBefore ${blBef/DT} ${crBef/DT} text $indent cr curr [html::CloseElem DT]
  428.             html::crAfter ${blAft/DT} ${crAft/DT} text indent cr curr 1 $indDT
  429.         }
  430.         if {$askForLiAttr} {
  431.             set text1 [html::OpenElem DD "" 0]
  432.         } else {
  433.             set text1 [html::SetCase <DD>]
  434.         }
  435.         html::crBefore $blBefDD $crBefDD text $indent cr curr [html::prepareForBreaking $text1]
  436.         html::crAfter $blAftDD $crAftDD text indent cr curr 0 $indDD
  437.         if {$i == 0 && $htmlIsSel} {
  438.             append curr [html::prepareForBreaking $Sel]
  439.         } elseif {$useTabMarks} {
  440.             append curr "•content•"
  441.         }
  442.         if {$containerDD} {
  443.             html::crBefore ${blBef/DD} ${crBef/DD} text $indent cr curr [html::CloseElem DD]
  444.             html::crAfter ${blAft/DD} ${crAft/DD} text indent cr curr 1 $indDD
  445.         }
  446.     }
  447.     
  448.     html::crBefore ${blBef/DL} ${crBef/DL} text $indent cr curr [html::CloseElem DL]
  449.     append text [html::BreakIntoLines $curr $indent]
  450.     if {${crAft/DL}} {append text [html::CloseCR]}
  451.     if {${blAft/DL}} {append text [html::CloseCR2 [selEnd]]}
  452.     if {$useTabMarks} {append text "•end•"}
  453.     if {$htmlIsSel} { deleteSelection }
  454.     html::elecInsertion text
  455. }
  456.  
  457. # Add an individual entry to a discursive list
  458. proc html::DefinitionEntry {} {
  459.     global htmlCurSel htmlIsSel HTMLmodeVars
  460.  
  461.     # Is in STYLE container?
  462.     if {[html::IsInContainer STYLE]} {replaceText [getPos] [selEnd] DT; return}
  463.  
  464.     set useTabMarks    $HTMLmodeVars(useTabMarks)
  465.     set containerDT [lcontains HTMLmodeVars(optionalClosing) DT]
  466.     set containerDD [lcontains HTMLmodeVars(optionalClosing) DD]
  467.     set indDT [lcontains HTMLmodeVars(indentElements) DT]
  468.     set indDD [lcontains HTMLmodeVars(indentElements) DT]
  469.     html::indentCR DT DD
  470.     
  471.     html::GetSel
  472.     set Sel $htmlCurSel
  473.     set indent ""
  474.     set curr ""
  475.     set text ""
  476.     set cr [expr {2 - [string length [html::OpenCR 1]]}]
  477.  
  478.     if {[set text1 [html::OpenElem DT "" 0]] == ""} {return}
  479.     html::crBefore $blBefDT $crBefDT text $indent cr curr [html::prepareForBreaking $text1]
  480.     html::crAfter $blAftDT $crAftDT text indent cr curr 0 $indDT
  481.     append curr "•content•"
  482.     if {$containerDT} {
  483.         html::crBefore ${blBef/DT} ${crBef/DT} text $indent cr curr [html::CloseElem DT]
  484.         html::crAfter ${blAft/DT} ${crAft/DT} text indent cr curr 1 $indDT
  485.     }
  486.     if {[set text1 [html::OpenElem DD "" 0]] == ""} {return}
  487.     html::crBefore $blBefDD $crBefDD text $indent cr curr [html::prepareForBreaking $text1]
  488.     html::crAfter $blAftDD $crAftDD text indent cr curr 0 $indDD
  489.     if {$htmlIsSel} {
  490.         append curr [html::prepareForBreaking $Sel]
  491.     } elseif {$useTabMarks} {
  492.         append curr "•content•"
  493.     }
  494.     if {$containerDD} {
  495.         html::crBefore ${blBef/DD} ${crBef/DD} text $indent cr curr [html::CloseElem DD]
  496.         append text [html::BreakIntoLines $curr $indent]
  497.         if {${crAft/DD}} {append text [html::CloseCR]}
  498.         if {${blAft/DD}} {append text [html::CloseCR2 [selEnd]]}
  499.         append text "•end•"
  500.     } else {
  501.         append text [html::BreakIntoLines $curr $indent] [html::CloseCR]
  502.     }
  503.     if {$htmlIsSel} { deleteSelection }
  504.     html::elecInsertion text
  505. }
  506.  
  507. #===============================================================================
  508. # ◊◊◊◊ Tables ◊◊◊◊ #
  509. #===============================================================================
  510.  
  511. # Table template. If there is any selection it is put in the first cell.
  512. proc html::TableTemplate {} {
  513.     global htmlCurSel htmlIsSel HTMLmodeVars
  514.     
  515.     set useTabMarks $HTMLmodeVars(useTabMarks)
  516.     set containerTR [lcontains HTMLmodeVars(optionalClosing) TR]
  517.     set containerTH [lcontains HTMLmodeVars(optionalClosing) TH]
  518.     set containerTD [lcontains HTMLmodeVars(optionalClosing) TD]
  519.     set indTABLE [lcontains HTMLmodeVars(indentElements) TABLE]
  520.     set indTR [lcontains HTMLmodeVars(indentElements) TR]
  521.     set indTD [lcontains HTMLmodeVars(indentElements) TD]
  522.     set indTH [lcontains HTMLmodeVars(indentElements) TH]
  523.     html::indentCR TABLE TR TH TD
  524.  
  525.     set values {"" "" 0 0 0}
  526.     set rows ""
  527.     set cols ""
  528.     set tableOpen [html::SetCase <TABLE>]
  529.     set trOpen [html::SetCase <TR>]
  530.     while {1} {
  531.         
  532.         set box "-t {Table template} 50 10 200 25 \
  533.         -p 50 26 150 27 \
  534.         -t {Number of rows} 10 40 150 55  -e [list [lindex $values 0]] 160 40 180 55 \
  535.         -t {Number of columns} 10 65 150 80 -e [list [lindex $values 1]] 160 65 180 80 \
  536.         -c {Table headers in first row} [lindex $values 2] 10 90 250 112 \
  537.         -c {Table headers in first column} [lindex $values 3] 10 112 250 134 \
  538.         -c {Don't insert TABLE tags} [lindex $values 4] 10 134 250 156 \
  539.         -b OK 20 250 85 270 -b Cancel 105 250 170 270\
  540.         -b {TABLE attributes…} 10 170 150 190 -b {TR attributes…} 10 200 150 220 "
  541.         
  542.         set values [eval [concat dialog -w 230 -h 280 $box]]
  543.         
  544.         # Cancel?
  545.         if {[lindex $values 6] } {return}
  546.         
  547.         set rows [lindex $values 0]
  548.         set cols [lindex $values 1]
  549.         set THrow [lindex $values 2]
  550.         set THcol [lindex $values 3]
  551.         set table [expr {![lindex $values 4]}]
  552.         if {[lindex $values 7]} {
  553.             if {!$table} {
  554.                 alertnote "You have chosen not to insert TABLE tags."
  555.             } elseif {[set tmp [html::ChangeElement [string range $tableOpen 1 [expr {[string length $tableOpen] - 2}]] TABLE]] != ""} {
  556.                 set tableOpen $tmp
  557.             }
  558.             continue
  559.         }
  560.         if {[lindex $values 8]} {
  561.             if {[set tmp [html::ChangeElement [string range $trOpen 1 [expr {[string length $trOpen] - 2}]] TR]] != ""} {
  562.                 set trOpen $tmp
  563.             }
  564.             continue
  565.         }
  566.         if {![is::PositiveInteger $rows] || ![is::PositiveInteger $cols] } {
  567.             alertnote "The number of rows and columns must be positive."
  568.         } else {
  569.             break
  570.         }
  571.     }
  572.     
  573.     html::GetSel
  574.     if {$htmlIsSel} {deleteSelection}
  575.     set indent ""
  576.     set curr ""
  577.     set text ""
  578.     set cr [expr {2 - [string length [html::OpenCR 1]]}]
  579.     if {$table} {
  580.         html::crBefore $blBefTABLE $crBefTABLE text $indent cr curr [html::prepareForBreaking $tableOpen]
  581.         html::crAfter $blAftTABLE $crAftTABLE text indent cr curr 0 $indTABLE
  582.     }
  583.     
  584.     for {set i 1} {$i <= $rows} {incr i} {
  585.         html::crBefore $blBefTR $crBefTR text $indent cr curr $trOpen
  586.         html::crAfter $blAftTR $crAftTR text indent cr curr 0 $indTR
  587.         for {set j 1} {$j <= $cols} {incr j} {
  588.             # Put TH in first row or column?
  589.             if {$i == 1 && $THrow || $j == 1 && $THcol} {
  590.                 set cell [html::SetCase TH]
  591.             } else {
  592.                 set cell [html::SetCase TD]
  593.             }
  594.             append curr "<$cell>"
  595.             if {$i == 1 && $j == 1 && $htmlIsSel} {
  596.                 append curr [html::prepareForBreaking $htmlCurSel]
  597.             } elseif {$useTabMarks} {
  598.                 append curr "•content•"
  599.             }
  600.             if {[set container$cell]} {
  601.                 html::crBefore [set blBef/$cell] [set crBef/$cell] text $indent cr curr [html::CloseElem $cell]
  602.                 if {$i == $rows && $j == $cols && !$containerTR && !$table} {
  603.                     append text [html::BreakIntoLines $curr $indent]
  604.                     if {[set crAft/$cell]} {append text [html::CloseCR]}
  605.                     if {[set blAft/$cell]} {append text [html::CloseCR2 [selEnd]]}
  606.                 } else {
  607.                     html::crAfter [set blAft/$cell] [set crAft/$cell] text indent cr curr 1 [set ind$cell]
  608.                 }                    
  609.             }
  610.         }
  611.         if {$containerTR} {
  612.             html::crBefore ${blBef/TR} ${crBef/TR} text $indent cr curr [html::CloseElem TR]
  613.             if {$i < $rows || $table} {
  614.                 html::crAfter ${blAft/TR} ${crAft/TR} text indent cr curr 1 $indTR
  615.             } else {
  616.                 append text [html::BreakIntoLines $curr $indent]
  617.                 if {${crAft/TR}} {append text [html::CloseCR]}
  618.                 if {${blAft/TR}} {append text [html::CloseCR2 [selEnd]]}
  619.             }
  620.         }
  621.     }
  622.     if {$table} {
  623.         html::crBefore ${blBef/TABLE} ${crBef/TABLE} text $indent cr curr [html::CloseElem TABLE]
  624.         append text [html::BreakIntoLines $curr $indent]
  625.         if {${crAft/TABLE}} {append text [html::CloseCR]}
  626.         if {${blAft/TABLE}} {append text [html::CloseCR2 [selEnd]]}
  627.     }
  628.     if {$useTabMarks && ($rows > 1 || $cols > 1 || !$htmlIsSel)} {append text "•end•"}
  629.     html::elecInsertion text
  630. }
  631.  
  632.  
  633. # Take table rows in a selection and remove the TR, TD and TH elements and
  634. # put tabs between the elements.
  635. proc html::RowstoTabs {} {
  636.     if {![isSelection]} {
  637.         beep
  638.         message "No selection."
  639.         return
  640.     }
  641.     
  642.     set startPos [getPos]
  643.     set endPos [selEnd]
  644.     if {[catch {search -s -f 1 -i 1 -r 1 -m 0 {<TR([ \t\r\n]+[^>]*>|>)} $startPos} res] || \
  645.       [pos::compare [lindex $res 1] > $endPos]} {
  646.         beep 
  647.         message "No table row in selection."
  648.         return
  649.     }
  650.     # Check that the selections begins with a table row.
  651.     set preText [getText $startPos [lindex $res 0]]
  652.     if {![is::Whitespace $preText]} {
  653.         beep
  654.         message "First part of selection is not in a table row."
  655.         return
  656.     }
  657.     # Extract each table row.
  658.     set startPos [lindex $res 1]
  659.     while {![catch {search -s -f 1 -i 1 -r 1 -m 0 {<TR([ \t\r\n]+[^>]*>|>)} $startPos} res2] && \
  660.       [pos::compare [lindex $res2 1] <= $endPos]} {
  661.         set text2 [getText $startPos [lindex $res2 0]]
  662.         regsub -all "\[\t\r\n\]+" $text2 " " text2
  663.         append text [string trim $text2] "\r"
  664.         set startPos [lindex $res2 1]
  665.     }
  666.     set text2 [getText $startPos $endPos]
  667.     regsub -all "\[\t\r\n\]+" $text2 " " text2
  668.     append text [string trim $text2]
  669.     
  670.     # Check that there is nothing after the last table row.
  671.     if {![catch {search -s -f 1 -i 1 -r 1 -m 0 {</TR>} $startPos} res] \
  672.       && [pos::compare [lindex $res 1] <= $endPos]} {
  673.         set preText [getText [lindex $res 1] $endPos]
  674.         if {![is::Whitespace $preText]} {
  675.             beep
  676.             message "Last part of selection not in a table row."
  677.             return
  678.         }
  679.     }
  680.     # Make the transformation.
  681.     foreach ln [split $text "\r"] {
  682.         if {![string length $ln]} continue
  683.         regsub -all {> +<} $ln "><" ln
  684.         regsub -all {<(t|T)(h|H|d|D)([ ]+[^>]*>|>)} $ln "\t" ln
  685.         regsub {    } $ln "" ln
  686.         regsub -all {</(t|T)(h|H|d|D|r|R)>} $ln "" ln
  687.         append out "$ln\r"
  688.     }
  689.     replaceText [getPos] [selEnd] $out
  690. }
  691.  
  692. # Convert tab-delimited format to table rows.
  693. # First row and first coloumn can optionally consist of table headers.
  694. proc html::ImportTable {} {html::TabstoRows file}
  695.  
  696. proc html::TabstoRows {{where selection}} {
  697.     global HTMLmodeVars
  698.     
  699.     set containerTR [lcontains HTMLmodeVars(optionalClosing) TR]
  700.     set containerTH [lcontains HTMLmodeVars(optionalClosing) TH]
  701.     set containerTD [lcontains HTMLmodeVars(optionalClosing) TD]
  702.     set indTABLE [lcontains HTMLmodeVars(indentElements) TABLE]
  703.     set indTR [lcontains HTMLmodeVars(indentElements) TR]
  704.     set indTD [lcontains HTMLmodeVars(indentElements) TD]
  705.     set indTH [lcontains HTMLmodeVars(indentElements) TH]
  706.     html::indentCR TABLE TR TH TD
  707.  
  708.     if {$where == "selection"} {
  709.         if {![isSelection]} {
  710.             beep
  711.             message "No selection."
  712.             return
  713.         }
  714.         set tabtext [string trim [getSelect] " \r\n"]
  715.         set newln [html::CRcharacter]
  716.         set htext "Tabs to Rows"
  717.     } else {
  718.         set fil [getfile "Select file with table."]
  719.         if {![html::IsTextFile $fil alertnote]} {return}
  720.         set fid [open $fil r]
  721.         set tabtext [string trim [read $fid] " \r\n"]
  722.         close $fid
  723.         if {[regexp {\n} $tabtext]} {
  724.             set newln "\n"
  725.         } else {
  726.             set newln "\r"
  727.         }
  728.         regsub -all "\n\r" $tabtext "\n" tabtext
  729.         set htext "Import table"
  730.     }
  731.     set values {0 0 0 0}
  732.     set tableOpen [html::SetCase <TABLE>]
  733.     set trOpen [html::SetCase <TR>]
  734.     while {1} {
  735.         
  736.         set box "-t [list $htext] 50 10 200 25 \
  737.         -p 50 26 150 27 \
  738.         -c {Table headers in first row} [lindex $values 0] 10 40 250 62 \
  739.         -c {Table headers in first column} [lindex $values 1] 10 62 250 84 \
  740.         -c {Don't insert TABLE tags} [lindex $values 2] 10 84 250 106 \
  741.         -c {Treat multiple tabs as one} [lindex $values 3] 10 106 250 128 \
  742.         -b OK 20 220 85 240 -b Cancel 105 220 170 240\
  743.         -b {TABLE attributes…} 10 140 150 160 -b {TR attributes…} 10 170 150 190 "
  744.         
  745.         set values [eval [concat dialog -w 230 -h 250 $box]]
  746.         
  747.         # Cancel?
  748.         if {[lindex $values 5] } {return}
  749.         
  750.         set THrow [lindex $values 0]
  751.         set THcol [lindex $values 1]
  752.         set table [expr {![lindex $values 2]}]
  753.         if {[lindex $values 3]} {
  754.             set tabexp "\t+"
  755.         } else {
  756.             set tabexp \t
  757.         }
  758.         if {[lindex $values 6]} {
  759.             if {!$table} {
  760.                 alertnote "You have chosen not to insert TABLE tags."
  761.             } elseif {[set tmp [html::ChangeElement [string range $tableOpen 1 [expr {[string length $tableOpen] - 2}]] TABLE]] != ""} {
  762.                 set tableOpen $tmp
  763.             }
  764.             continue
  765.         }
  766.         if {[lindex $values 7]} {
  767.             if {[set tmp [html::ChangeElement [string range $trOpen 1 [expr {[string length $trOpen] - 2}]] TR]] != ""} {
  768.                 set trOpen $tmp
  769.             }
  770.             continue
  771.         }
  772.         break
  773.     }
  774.                 
  775.     set indent ""
  776.     set curr ""
  777.     set text ""
  778.     set cr [expr {2 - [string length [html::OpenCR 1]]}]
  779.     if {$table} {
  780.         html::crBefore $blBefTABLE $crBefTABLE text $indent cr curr [html::prepareForBreaking $tableOpen]
  781.         html::crAfter $blAftTABLE $crAftTABLE text indent cr curr 0 $indTABLE
  782.     }
  783.  
  784.     set lines [split $tabtext $newln]
  785.     set i 1
  786.     foreach ln $lines {
  787.         if {![string length $ln]} {
  788.             incr i
  789.             continue
  790.         } else {
  791.             html::crBefore $blBefTR $crBefTR text $indent cr curr [html::prepareForBreaking $trOpen]
  792.             html::crAfter $blAftTR $crAftTR text indent cr curr 0 $indTR
  793.             # Should there be headers in the first row?
  794.             if {$i == 1 && $THrow} {
  795.                 set cell TH
  796.             } else {
  797.                 set cell TD
  798.             }
  799.             # Should there be headers in the first column?
  800.             if {$THcol || ($i == 1 && $THrow)} {
  801.                 set fcell TH
  802.             } else {
  803.                 set fcell TD
  804.             }
  805.             set tabs 0
  806.             html::crBefore [set blBef$fcell] [set crBef$fcell] text $indent cr curr [html::SetCase <$fcell>]
  807.             html::crAfter [set blAft$fcell] [set crAft$fcell] text indent cr curr 0 [set ind$fcell]
  808.             while {[regexp -indices $tabexp $ln t]} {
  809.                 append curr [html::prepareForBreaking [string range $ln 0 [expr {[lindex $t 0] - 1}]]]
  810.                 if {$tabs} {
  811.                     set lcell $cell
  812.                 } else {
  813.                     set lcell $fcell
  814.                 }
  815.                 if {[set container$lcell]} {
  816.                     html::crBefore [set blBef/$lcell] [set crBef/$lcell] text $indent cr curr [html::CloseElem $lcell]
  817.                     html::crAfter [set blAft/$lcell] [set crAft/$lcell] text indent cr curr 1 [set ind$lcell]
  818.                 }
  819.                 html::crBefore [set blBef$cell] [set crBef$cell] text $indent cr curr [html::SetCase <$cell>]
  820.                 html::crAfter [set blAft$cell] [set crAft$cell] text indent cr curr 0 [set ind$cell]
  821.                 set ln [string range $ln [expr {[lindex $t 1] + 1}] end]
  822.                 incr tabs
  823.             }
  824.             append curr [html::prepareForBreaking $ln]
  825.             # Add cell or fcell closing, depending on if there is more than one cell.
  826.             if {$tabs} {
  827.                 set lcell $cell
  828.             } else {
  829.                 set lcell $fcell
  830.             }
  831.             if {[set container$lcell]} {
  832.                 html::crBefore [set blBef/$lcell] [set crBef/$lcell] text $indent cr curr [html::CloseElem $lcell]
  833.                 if {$i == [llength $lines] && !$containerTR && !$table} {
  834.                     append text [html::BreakIntoLines $curr $indent]
  835.                     if {[set crAft/$lcell]} {append text [html::CloseCR]}
  836.                     if {[set blAft/$lcell]} {append text [html::CloseCR2 [selEnd]]}
  837.                 } else {
  838.                     html::crAfter [set blAft/$lcell] [set crAft/$lcell] text indent cr curr 1 [set ind$lcell]
  839.                 }                    
  840.             }
  841.             if {$containerTR} {
  842.                 html::crBefore ${blBef/TR} ${crBef/TR} text $indent cr curr [html::CloseElem TR]
  843.                 if {$i < [llength $lines] || $table} {
  844.                     html::crAfter ${blAft/TR} ${crAft/TR} text indent cr curr 1 $indTR
  845.                 } else {
  846.                     append text [html::BreakIntoLines $curr $indent]
  847.                     if {${crAft/TR}} {append text [html::CloseCR]}
  848.                     if {${blAft/TR}} {append text [html::CloseCR2 [selEnd]]}
  849.                 }
  850.             }
  851.         }
  852.         incr i
  853.     }
  854.     if {$table} {
  855.         html::crBefore ${blBef/TABLE} ${crBef/TABLE} text $indent cr curr [html::CloseElem TABLE]
  856.         append text [html::BreakIntoLines $curr $indent]
  857.         if {${crAft/TABLE}} {append text [html::CloseCR]}
  858.         if {${blAft/TABLE}} {append text [html::CloseCR2 [selEnd]]}
  859.     }
  860.     if {$where == "selection"} {
  861.         deleteText [getPos] [selEnd]
  862.         HTML::indentLine
  863.         if {[pos::compare [set p [text::firstNonWsLinePos [getPos]]] > [getPos]]} {goto $p}
  864.         elec::Insertion $text
  865.     } else {
  866.         html::elecInsertion text
  867.     }
  868. }
  869.  
  870. #===============================================================================
  871. # ◊◊◊◊ Image maps ◊◊◊◊ #
  872. #===============================================================================
  873.  
  874. # Converts an NCSA or CERN image map file to a client side image map.
  875. proc html::ConvertNCSAMap {} {html::ConvertMap NCSA}
  876. proc html::ConvertCERNMap {} {html::ConvertMap CERN}
  877.  
  878. proc html::ConvertMap {type} {
  879.     global HTMLmodeVars
  880.     
  881.     if {[catch {getfile "Select the $type image map file."} fil] || ![html::IsTextFile $fil alertnote] ||
  882.     [catch {open $fil r} fid]} {return}
  883.     set filecont [read $fid]
  884.     close $fid
  885.     if {[regexp {\n} $filecont]} {
  886.         set newln "\n"
  887.     } else {
  888.         set newln "\r"
  889.     }
  890.     if {![string length [set map [html::OpenElem MAP "" 0]]]} {return}
  891.     html::indentCR MAP AREA
  892.     set aind ""
  893.     if {[lcontains HTMLmodeVars(indentElements) MAP]} {set aind "\t"}
  894.     set indent ""
  895.     set curr ""
  896.     set out ""
  897.     set cr [expr {2 - [string length [html::OpenCR 1]]}]
  898.     html::crBefore $blBefMAP $crBefMAP out $indent cr curr [html::prepareForBreaking $map]
  899.     html::crAfter $blAftMAP $crAftMAP out indent cr curr 0 [lcontains HTMLmodeVars(indentElements) MAP]
  900.     html::${type}map [split $filecont $newln] notknown invalid out curr cr $aind
  901.     if {$invalid} {
  902.         if {[askyesno "Some lines in [file tail $fil] have invalid syntax. They are ignored. Continue?"] == "no"} {return}
  903.     } elseif {$notknown} {
  904.         if {[askyesno "Some lines in [file tail $fil] specify a shape not supported. They are ignored. Continue?"] == "no"} {return}
  905.     }
  906.     html::crBefore ${blBef/MAP} ${crBef/MAP} out $indent cr curr [html::CloseElem MAP]
  907.     append out [html::BreakIntoLines $curr $indent]
  908.     if {${crAft/MAP}} {append out [html::CloseCR]}
  909.     if {${blAft/MAP}} {append out [html::CloseCR2 [getPos]]}
  910.     html::elecInsertion out
  911. }
  912.  
  913. proc html::NCSAmap {lines nknw sinv ar crr c indent} {
  914.     upvar $nknw notknown $sinv someinvalid $ar area $crr curr $c cr
  915.     set notknown 0
  916.     set someinvalid 0
  917.     set defarea ""
  918.     html::indentCR AREA
  919.     foreach l $lines {
  920.         set invalid 0
  921.         set l [string trim $l]
  922.         # Skip comments and blank lines
  923.         if {[regexp {^#} $l] || ![string length $l]} {continue}
  924.         set shape [string toupper [lindex $l 0]]
  925.         if {[lsearch {RECT CIRCLE POLY DEFAULT} $shape] < 0} {
  926.             set notknown 1
  927.             continue
  928.         }
  929.         set url [lindex $l 1]
  930.         set exp "^\[0-9\]+,\[0-9\]+$"
  931.         if {[regexp $exp $url]} {
  932.             set url ""
  933.             set cind 1
  934.         } else {
  935.             set cind 2
  936.         }
  937.         switch $shape {
  938.             RECT {
  939.                 if {[regexp $exp [lindex $l $cind]] && [regexp $exp [lindex $l [expr {$cind + 1}]]]} {
  940.                     set coord "[lindex $l $cind],[lindex $l [expr {$cind + 1}]]"
  941.                 } else {
  942.                     set invalid 1
  943.                 }
  944.             }
  945.             CIRCLE {
  946.                 if {[regexp $exp [lindex $l $cind] cent] && [regexp $exp [lindex $l [expr {$cind + 1}]] edge]} {
  947.                     regexp {[0-9]+} $cent xc
  948.                     regexp {[0-9]+} $edge xe
  949.                     set coord "$cent,[expr {$xe-$xc}]"
  950.                 } else {
  951.                     set invalid 1
  952.                 }
  953.             }
  954.             POLY {
  955.                 set coord ""
  956.                 foreach c [lrange $l $cind end] {
  957.                     if {![regexp $exp $c]} {
  958.                         set invalid 1
  959.                         break
  960.                     }
  961.                     append coord "$c,"
  962.                 }
  963.                 set coord [string trimright $coord ,]
  964.             }
  965.         }
  966.         if {!$invalid} {
  967.             set tmp "<[html::SetCase "AREA SHAPE=\"$shape\""]"
  968.             if {$shape != "DEFAULT"} {
  969.                 append tmp " [html::SetCase COORDS]=\"$coord\""
  970.             }
  971.             if {[string length $url]} {
  972.                 append tmp " [html::SetCase HREF]=\"$url\""
  973.             } else {
  974.                 append tmp " [html::SetCase NOHREF]"
  975.             }
  976.             append tmp ">"
  977.             if {$shape != "DEFAULT"} {
  978.                 html::crBefore $blBefAREA $crBefAREA area $indent cr curr $tmp
  979.                 html::crAfter $blAftAREA $crAftAREA area indent cr curr 0 0
  980.             } else {
  981.                 set defarea $tmp
  982.             }
  983.         } else {
  984.             set someinvalid 1
  985.         }
  986.     }
  987.     if {$defarea != ""} {
  988.         html::crBefore $blBefAREA $crBefAREA area $indent cr curr $defarea
  989.         html::crAfter $blAftAREA $crAftAREA area indent cr curr 0 0
  990.     }
  991. }
  992.  
  993. proc html::CERNmap {lines nknw sinv ar crr c indent} {
  994.     upvar $nknw notknown $sinv someinvalid $ar area $crr curr $c cr
  995.     set notknown 0
  996.     set someinvalid 0
  997.     set defarea ""
  998.     html::indentCR AREA
  999.     foreach l $lines {
  1000.         set invalid 0
  1001.         set l [string trim $l]
  1002.         # Skip comments and blank lines
  1003.         if {[regexp {^#} $l] || ![string length $l]} {continue}
  1004.         set shape [string toupper [lindex $l 0]]
  1005.         if {![string match RECT* $shape] && ![string match CIRC* $shape] &&
  1006.         ![string match POLY* $shape] && ![string match DEFAULT $shape]} {
  1007.             set notknown 1
  1008.             continue
  1009.         }
  1010.         set exp "^\\(\[0-9\]+,\[0-9\]+\\)$"
  1011.         switch -glob $shape {
  1012.             RECT* {
  1013.                 set url [lindex $l 3]
  1014.                 if {[regexp $exp [lindex $l 1]] && [regexp $exp [lindex $l 2]]} {
  1015.                     set coord "[string trimleft [string trimright [lindex $l 1] )] (],[string trimleft [string trimright [lindex $l 2] )] (]"
  1016.                     set shape RECT
  1017.                 } else {
  1018.                     set invalid 1
  1019.                 }
  1020.             }
  1021.             CIRC* {
  1022.                 set url [lindex $l 3]
  1023.                 if {[regexp $exp [lindex $l 1]] && [regexp {^[0-9]+$} [lindex $l 2]]} {
  1024.                     set coord "[string trimleft [string trimright [lindex $l 1] )] (],[lindex $l 2]"
  1025.                     set shape CIRCLE
  1026.                 } else {
  1027.                     set invalid 1
  1028.                 }
  1029.             }
  1030.             POLY* {
  1031.                 set coord ""
  1032.                 set url [lindex $l [expr {[llength $l] - 1}]]
  1033.                 if {[regexp $exp $url]} {
  1034.                     set url ""
  1035.                     set cind 1
  1036.                 } else {
  1037.                     set cind 2
  1038.                 }
  1039.                 foreach c [lrange $l 1 [expr {[llength $l] - $cind}]] {
  1040.                     if {![regexp $exp $c]} {
  1041.                         set invalid 1
  1042.                         break
  1043.                     }
  1044.                     append coord "[string trimleft [string trimright $c )] (],"
  1045.                 }
  1046.                 set coord [string trimright $coord ,]
  1047.                 set shape POLY
  1048.             }
  1049.             DEFAULT {
  1050.                 set url [lindex $l 1]
  1051.             }
  1052.         }
  1053.         if {!$invalid} {
  1054.             set tmp "<[html::SetCase "AREA SHAPE=\"$shape\""]"
  1055.             if {$shape != "DEFAULT"} {
  1056.                 append tmp " [html::SetCase COORDS]=\"$coord\""
  1057.             }
  1058.             if {[string length $url]} {
  1059.                 append tmp " [html::SetCase HREF]=\"$url\""
  1060.             } else {
  1061.                 append tmp " [html::SetCase NOHREF]"
  1062.             }
  1063.             append tmp ">"
  1064.             if {$shape != "DEFAULT"} {
  1065.                 html::crBefore $blBefAREA $crBefAREA area $indent cr curr $tmp
  1066.                 html::crAfter $blAftAREA $crAftAREA area indent cr curr 0 0
  1067.             } else {
  1068.                 set defarea $tmp
  1069.             }
  1070.         } else {
  1071.             set someinvalid 1
  1072.         }
  1073.     }
  1074.     if {$defarea != ""} {
  1075.         html::crBefore $blBefAREA $crBefAREA area $indent cr curr $defarea
  1076.         html::crAfter $blAftAREA $crAftAREA area indent cr curr 0 0
  1077.     }
  1078. }
  1079.  
  1080. #===============================================================================
  1081. # ◊◊◊◊ Comments ◊◊◊◊ #
  1082. #===============================================================================
  1083.  
  1084. proc html::Comment {} {
  1085.     global htmlCurSel htmlIsSel HTMLmodeVars
  1086.     set comStrs [html::CommentStrings]
  1087.     html::GetSel
  1088.     if {$htmlIsSel} { 
  1089.         deleteSelection 
  1090.         set text2 $htmlCurSel
  1091.     } else {
  1092.         append text2 "•comment•"
  1093.     }
  1094.     if {[lindex $comStrs 0] == "/* "} {
  1095.         elec::Insertion [lindex $comStrs 0] $text2 [lindex $comStrs 1]
  1096.         return
  1097.     }
  1098.     if {[is::Whitespace [getText [lineStart [getPos]] [getPos]]]
  1099.     && [pos::compare [lineStart [getPos]] > [minPos]]} {goto [pos::math [lineStart [getPos]] - 1]}
  1100.     set text "[html::OpenCR][lindex $comStrs 0]$text2"
  1101.     append text [lindex $comStrs 1] [html::CloseCR]
  1102.     if {!$htmlIsSel && $HTMLmodeVars(useTabMarks)} {append text "•end•"}
  1103.     html::elecInsertion text
  1104. }
  1105.  
  1106. #
  1107. # dividing line
  1108. #
  1109. proc html::CommentLine {} {
  1110.     global HTMLmodeVars fillColumn
  1111.     set wordWrap $HTMLmodeVars(wordWrap)
  1112.     set comStr    [html::CommentStrings]
  1113.     set prefixString [lindex $comStr 0]
  1114.     set suffixString [lindex $comStr 1]
  1115.     set s "===================================================================================="
  1116.     set l [expr {[string length $prefixString] + [string length $suffixString]}]
  1117.     if {$wordWrap} { 
  1118.         set l [expr {$fillColumn - $l - 1}] 
  1119.     } else {
  1120.         set l [expr {75 - $l - 1}]
  1121.     }
  1122.     elec::Insertion [html::OpenCR] $prefixString [string range $s 0 $l] $suffixString "\r"
  1123. }
  1124.  
  1125.  
  1126.